home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d882.lha
/
GALer
/
GALer_english
/
Source
/
GALerSrcE.lha
/
Optimizer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-26
|
41KB
|
1,493 lines
/****************************************************************/
/* */
/* Optimizer.c - dieses Modul enthält den Optimierer für */
/* die Booleschen Ausdrücke */
/* */
/* Funktionsweise des Optimierers: */
/* Zunächst wird das normale Source-File "name.pld" geladen */
/* und bis zu den Gleichungen so ausgewertet als ob es assem- */
/* bliert werden soll. Das heißt: Bei Verstößen gegen die */
/* Syntax wird abgebrochen. */
/* Wenn bis dahin kein Fehler aufgetreten ist, werden die */
/* Gleichungen codiert (Zahlen anstatt Strings) in den Speicher */
/* abgelegt. Wenn dabei kein Fehler auftrat, wird mit Hilfe */
/* des Quine-McCluskey - Algorithmus versucht, die Gleichungen */
/* zu vereinfachen. */
/* Zum Schluß werden die codierten (und vereinfachten) Gleich- */
/* ungen wieder in Textform zurückgewandelt und abgespeichert. */
/* */
/* */
/* compilieren: cc Optimizer.c */
/* */
/****************************************************************/
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <functions.h>
#include <stdio.h>
#include "GALer.h"
#define TAKEIT_GADID 1
#define FORGETIT_GADID 2
#define WEITER_GADID 10
extern int num_of_pins, asmreadyflag, gal_type, num_of_col;
extern LONG fsize;
extern UBYTE *fbuff;
extern UBYTE *actptr, *buffend;
extern UBYTE PinNamesOpt[24][10];
extern char path[];
extern struct Pin actPin;
extern struct Screen *screen;
extern struct Window *window;
extern struct Menu Menu1;
struct RastPort *orp; /*RastPort für Optimizer-Window*/
struct Window *optwin;
UBYTE OptTxt1[] = "optimized equation xxxx:";
int oypos, scrolls, reqflag;
int num_of_ORs, num_of_ANDs;
int numofpins_Opt;
/*oypos: y-Pos. für Text im Optimizer-Window*/
/*scrolls: wie oft gescrollt wurde*/
/*reqflag: Scrollreq. ja oder nein ?*/
SHORT OBorderVectors1a[] = { 0,12,96,12,96,0 };
SHORT OBorderVectors1b[] = { 0,12,0,0,96,0 };
SHORT OBorderVectors2a[] = { 0,47,344,47,344,0 };
SHORT OBorderVectors2b[] = { 0,47,0,0,344,0 };
SHORT OBorderVectors3a[] = { 0,12,96,12,96,0 };
SHORT OBorderVectors3b[] = { 0,12,0,0,96,0 };
SHORT OBorderVectors4a[] = { 0,12,73,12,73,0 };
SHORT OBorderVectors4b[] = { 0,12,0,0,73,0 };
SHORT SRBorVeca[] = { 0,59,349,59,349,0 };
SHORT SRBorVecb[] = { 0,59,0,0,349,0 };
struct Border OBorder1b = { -1,-1,2,0,JAM1,3,OBorderVectors1b,NULL };
struct Border OBorder1a = { -1,-1,1,0,JAM1,3,OBorderVectors1a,&OBorder1b };
struct Border OBorder2b = { -1,-1,2,0,JAM1,3,OBorderVectors2b,NULL };
struct Border OBorder2a = { -1,-1,1,0,JAM1,3,OBorderVectors2a,&OBorder2b };
struct Border OBorder3b = { -1,-1,2,0,JAM1,5,OBorderVectors3b,NULL };
struct Border OBorder3a = { -1,-1,1,0,JAM1,5,OBorderVectors3a,&OBorder3b };
struct Border OBorder4b = { -1,-1,2,0,JAM1,3,OBorderVectors4b,NULL };
struct Border OBorder4a = { -1,-1,1,0,JAM1,3,OBorderVectors4a,&OBorder4b };
struct Border SRBorderb = { 0,0,2,0,JAM1,3,SRBorVecb,NULL };
struct Border SRBordera = { 0,0,1,0,JAM1,3,SRBorVeca,&SRBorderb };
struct IntuiText OIText1 = { 2,0,JAM2,12,2,NULL,
(UBYTE *)" reject",NULL };
struct IntuiText OIText2 = { 2,0,JAM2,8,2,NULL,
(UBYTE *)" use it",NULL };
struct IntuiText OIText4 = { 2,0,JAM1,13,2,NULL,
(UBYTE *)" Cont",NULL };
struct IntuiText OIText5 = { 2,0,JAM1,13,10,NULL,
(UBYTE *)"press any key or select 'Cont'",
NULL };
UBYTE opttitle[] = "Optimizer";
struct Gadget OGadget3 = { NULL,521,169,95,11,NULL,
RELVERIFY,
BOOLGADGET,
(APTR)&OBorder1a,
NULL,&OIText1,NULL,NULL,FORGETIT_GADID,NULL };
struct Gadget OGadget1 = { &OGadget3,389,169,95,11,NULL,
RELVERIFY,
BOOLGADGET,
(APTR)&OBorder1a,
NULL,&OIText2,NULL,NULL,TAKEIT_GADID,NULL };
struct Gadget OGadget2 = { NULL,138,38,72,11,
NULL,
RELVERIFY,
BOOLGADGET+REQGADGET,
(APTR)&OBorder4a,NULL,
&OIText4,NULL,NULL,WEITER_GADID,NULL };
struct NewWindow OptWindow = { 0,0,640,200,0,1,
GADGETUP+VANILLAKEY,
WINDOWDEPTH+ACTIVATE+NOCAREREFRESH,
&OGadget1,NULL,
(UBYTE *)opttitle,
NULL,NULL,5,5,-1,-1,
CUSTOMSCREEN };
struct Requester ScrollReq = { NULL,150,138,350,60,0,0,
&OGadget2,&SRBordera,&OIText5,
NOISYREQ,3,NULL,NULL,NULL };
/* Optimizer - Boolesche Gleichungen vereinfachen
Paramter: ---
Ergegnis: 0: alles o.k. sonst: Fehler oder Abbruch
*/
int Optimizer()
{
struct IntuiMessage *imsg;
struct ActBuffer AllEquas, OptEqua, FileEquas;
struct Buffer *FirstAllEquas, *FirstOptEqua, *FirstFileEquas;
ULONG class;
USHORT code, gadID;
UBYTE *equastart, *equaend; /*Gleichungsanfang und -ende*/
int n, equaflag, asmreadyflag2, gal_type2, num_of_pins2, num_of_col2;
char statstrng[6];
/*AllEquas: Puffer in dem alle Gleichungen*/
/*codiert abgelegt sind*/
/*FirstAllEquas: Zeiger auf den ersten Puffer*/
/*in dem alle Gleichung stehen*/
/*OptEqua: Puffer in dem eine Gleichung*/
/*optimiert wird*/
/*FileEquas: Puffer in dem Gleichungen in*/
/*String-Form (!) abgelegt werden, um daraus*/
/*dann ein neues Source-File zu erstellen*/
/*FirstOptEquas: Zeiger auf den ersten Puffer*/
/*in dem die Gleichung optimiert wird*/
asmreadyflag2 = asmreadyflag; /*die Variablen, die wichtig sind und*/
gal_type2 = gal_type; /*in "AssembleInputFile" verändert*/
num_of_pins2 = num_of_pins; /*werden, sichern*/
num_of_col2 = num_of_col;
/*zum "Schein" assemblieren, dadurch spar*/
n = AssembleInputFile(OPTIMIZER); /*ich mir den Syntax-Check, da das der*/
/*Assembler jetzt macht*/
numofpins_Opt = num_of_pins;
asmreadyflag = asmreadyflag2; /*Variablen wieder herstellen*/
gal_type = gal_type2;
num_of_pins = num_of_pins2;
num_of_col = num_of_col2;
if (!n) {
equastart = actptr;
if (!(FirstAllEquas = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
ErrorReq(2); /*kein Speicher mehr->Fehlermeldung*/
return(-1);
}
AllEquas.ThisBuff = FirstAllEquas;
AllEquas.Entry = (UBYTE *)(&FirstAllEquas->Entries[0]);
AllEquas.BuffEnd = (UBYTE *)FirstAllEquas + (long)sizeof(struct Buffer);
if (!TranslateEqua(&AllEquas)) {
equaend = actptr; /*Zeiger auf DESCRIPTION merken*/
if (!(FirstFileEquas = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstAllEquas); /*Puffer für Gleichungen*/
ErrorReq(2); /*kein Speicher mehr->Fehlermeldung*/
return(-1);
}
FileEquas.ThisBuff = FirstFileEquas;
FileEquas.Entry = (UBYTE *)(&FirstFileEquas->Entries[0]);
FileEquas.BuffEnd = (UBYTE *)FirstFileEquas + (long)sizeof(struct Buffer);
if (AddByte(&FileEquas,0x0A)) { /*vor den Gleichungen in*/
FreeMem(fbuff, fsize); /*String-From noch einige*/
FreeBuffer(FirstAllEquas); /*Returns einfügen*/
FreeBuffer(FirstFileEquas);
ErrorReq(2);
return(-1);
}
if (AddByte(&FileEquas,0x0A)) {
FreeMem(fbuff, fsize);
FreeBuffer(FirstAllEquas);
FreeBuffer(FirstFileEquas);
ErrorReq(2);
return(-1);
}
OptWindow.Screen=screen;
if(!(optwin=(struct Window *)OpenWindow(&OptWindow))) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstAllEquas); /*Puffer für Gleichungen*/
FreeBuffer(FirstFileEquas); /*Puffer Gleichungen in String-Form*/
ErrorReq(12);
return(-1);
}
orp = optwin->RPort;
DrawBorder(orp,&OBorder2a,18L,145L);
ClearMenuStrip(window);
n = 0;
AllEquas.ThisBuff = FirstAllEquas;
AllEquas.Entry = (UBYTE *)(&FirstAllEquas->Entries[0]);
AllEquas.BuffEnd = (UBYTE *)FirstAllEquas + (long)sizeof(struct Buffer);
equaflag = TRUE; /*Gleichungen vorhanden*/
while (equaflag) {
SetAPen(orp,0L);
RectFill(orp,30L,23L,630L,142L); /*Bildschirm löschen*/
SetAPen(orp,2L);
oypos = 20; /*Variablen initialisieren*/
scrolls = 0;
reqflag = TRUE;
PrintOptText((UBYTE *)"old equation:");
PrintEqua(AllEquas,NULL);
Move(orp, 30L, 158L);
Text(orp, (UBYTE *)"Statistics: ORs ANDs", 38L);
Move(orp, 30L, 170L);
Text(orp, (UBYTE *)"old equation: ", 15L);
sprintf(&statstrng[0],"%4d",num_of_ORs);
Move(orp, 206L, 170L);
Text(orp, (UBYTE *)statstrng, 4L);
sprintf(&statstrng[0],"%4d",num_of_ANDs);
Move(orp, 294L, 170L);
Text(orp, (UBYTE *)statstrng, 4L);
if (!(FirstOptEqua = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstAllEquas); /*Puffer für Gleichungen*/
FreeBuffer(FirstFileEquas); /*Puffer Gleichungen in String-Form*/
CloseWindow(optwin);
SetMenuStrip(window,&Menu1);
ErrorReq(2); /*kein Speicher mehr->Fehlermeldung*/
return(-1);
}
OptEqua.ThisBuff = FirstOptEqua;
OptEqua.Entry = (UBYTE *)(&FirstOptEqua->Entries[0]);
OptEqua.BuffEnd = (UBYTE *)FirstOptEqua + (long)sizeof(struct Buffer);
/*Gleichung in den Optimizer-Puffer kopieren*/
if (CopyEqua(AllEquas,OptEqua)) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstAllEquas); /*Puffer für Gleichungen*/
FreeBuffer(FirstOptEqua); /*Puffer für Optimierer*/
FreeBuffer(FirstFileEquas); /*Puffer Gleichungen in String-Form*/
CloseWindow(optwin);
ErrorReq(2); /*kein Speicher mehr->Fehlermeldung*/
SetMenuStrip(window,&Menu1);
return(-1);
}
Move(orp, 30L, 180L);
Text(orp, (UBYTE *)"optimized equation: ", 21L);
sprintf(&statstrng[0]," -");
Move(orp, 206L, 180L);
Text(orp, (UBYTE *)statstrng, 4L);
sprintf(&statstrng[0]," -");
Move(orp, 294L, 180L);
Text(orp, (UBYTE *)statstrng, 4L);
/*versuche die Gleichung zu optimieren*/
SetWindowTitles(optwin, (UBYTE *)"please wait...(a few days - just a joke, I hope)", -1L);
if (OptimizeEqua(OptEqua)) {
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstAllEquas); /*Puffer für Gleichungen*/
FreeBuffer(FirstOptEqua); /*Puffer für Optimierer*/
FreeBuffer(FirstFileEquas); /*Puffer Gleichungen in String-Form*/
CloseWindow(optwin);
ErrorReq(2); /*kein Speicher mehr->Fehlermeldung*/
SetMenuStrip(window,&Menu1);
return(-1);
}
SetWindowTitles(optwin, (UBYTE *)opttitle, -1L);
PrintOptText((UBYTE *)"optimized equation:");
PrintEqua(OptEqua,NULL);
Move(orp, 30L, 180L);
Text(orp, (UBYTE *)"optimized equation: ", 21L);
sprintf(&statstrng[0],"%4d",num_of_ORs);
Move(orp, 206L, 180L);
Text(orp, (UBYTE *)statstrng, 4L);
sprintf(&statstrng[0],"%4d",num_of_ANDs);
Move(orp, 294L, 180L);
Text(orp, (UBYTE *)statstrng, 4L);
n++;
sprintf(&OptTxt1[21],"%d",n);
strcat(&OptTxt1[0],(UBYTE *)":");
Move(orp,389L,156L);
Text(orp, &OptTxt1[0], (long)strlen(&OptTxt1[0]));
for (;;) {
imsg = (struct IntuiMessage *)GetMsg(optwin->UserPort);
if (!imsg) WaitPort (optwin->UserPort);
else {
class = imsg->Class;
code = imsg->Code;
if (class==GADGETUP) gadID=((struct Gadget *)imsg->IAddress)->GadgetID;
ReplyMsg(imsg);
if (class == VANILLAKEY) {
if ((char)code == 'ü') { /*Übernehmen*/
PrintEqua(OptEqua,&FileEquas);
break;
}
if (code == 'v') { /*Verwerfen*/
PrintEqua(AllEquas,&FileEquas);
break;
}
}
if (class == GADGETUP) {
if (gadID == TAKEIT_GADID) { /*Übernehmen*/
PrintEqua(OptEqua,&FileEquas);
break;
}
if (gadID == FORGETIT_GADID) { /*Verwerfen*/
PrintEqua(AllEquas,&FileEquas);
break;
}
}
}
}
FreeBuffer(FirstOptEqua);
equaflag = GetNextEqua(&AllEquas);
}
CloseWindow(optwin);
SetMenuStrip(window,&Menu1);
/*neues Source-File erstellen*/
FileEquas.ThisBuff = FirstFileEquas;
FileEquas.Entry = (UBYTE *)(&FirstFileEquas->Entries[0]);
FileEquas.BuffEnd = (UBYTE *)FirstFileEquas + (long)sizeof(struct Buffer);
if (MyFileReq((char *)"save new source file", (char *)".pld", YES)) {
PrintText((UBYTE *)"saving source file...",1);
if (WriteNewSource(FileEquas, equastart, equaend)) {
PrintText((UBYTE *)" Error!",0);
MyRequest(ERR_REQ, (UBYTE *)"write error!");
}
else
PrintText((UBYTE *)" o.k.",0);
}
FreeMem(fbuff, fsize); /*Puffer für zu optimierendes File*/
FreeBuffer(FirstFileEquas); /*Puffer Gleichungen in String-Form*/
}
FreeBuffer(FirstAllEquas);
}
return(0);
}
/* GetProdTermStart: sucht den Anfang des Produktterms in den "pos" zeigt
Aufruf : prodpos = GetProdTermStart(pos);
Parameter: pos : ActBuffer-Struktur für Produktterm, dessen Anfang
gesucht werden soll
Ergebnis : prodpos : ActBuffer-Struktur für den Produkttermanfang
*/
struct ActBuffer GetProdTermStart(pos)
struct ActBuffer pos;
{
while(*pos.Entry) {
if (*pos.Entry == '+') {
IncPointer(&pos);
return(pos);
}
DecPointer(&pos);
}
IncPointer(&pos);
return(pos);
}
/* KillProdTerm: löscht einen Produktterm "term" aus der Gleichung,
in dem der Term mit EQUASKIP überschrieben wird
Aufruf : KillProdTerm(term);
Parameter : term: ActBuffer-Struktur für den Produktterm
Ergebnis : ---
*/
void KillProdTerm(term)
struct ActBuffer term;
{
struct ActBuffer start;
start = term;
while((*term.Entry) && (*term.Entry != '+')) {
*term.Entry = EQUASKIP;
IncPointer(&term);
}
if (*term.Entry == '+')
*term.Entry = EQUASKIP;
if (!*term.Entry) {
while((*start.Entry) && (*start.Entry != '+'))
DecPointer(&start);
if (*start.Entry == '+')
*start.Entry = EQUASKIP;
}
}
/* OptimizeEqua: Dies ist die eigentliche Routine, mit der die
Boolesche Gleichung vereinfacht wird.
Aufruf : result = OptimizeEqua(buff);
Parameter: buff: ActBuffer-Struktur der zu optimierenden Gleichung
Ergebnis : result = 0: alles o.k.
= -1: Fehler: kein freier Speicher mehr
*/
int OptimizeEqua(buff)
struct ActBuffer buff;
{
struct ActBuffer optend, pos1, pos2, pos3, prodterm1, prodterm2;
UBYTE merker;
int varfound, prodfound, result;
optend = buff;
while (*optend.Entry != EQUAEND) /*Gleichungsende suchen*/
IncPointer (&optend);
*optend.Entry = 0; /*Gleichungsende anstatt mit EQUAEND*/
/*mit 0 kennzeichnen*/
/*Gleichungsanfang durch '0'*/
/*kennzeichnen*/
IncPointer (&buff); /*erster Eintrag ist Ausgangspin*/
if (!((*buff.Entry=='T')||(*buff.Entry=='R')||(*buff.Entry=='E')))
DecPointer (&buff); /*.T, .R, .E berücksichtigen*/
merker = *buff.Entry; /*Zeichen merken*/
*buff.Entry = 0; /*Markierung setzen*/
/*optend = Gleichungsende*/
IncPointer (&buff); /*Zeiger auf erstes Zeichen*/
if (!*buff.Entry) { /*kein Zeichen da?*/
if (AddByte(&buff, numofpins_Opt/2)) /*GND eintragen*/
return(-1); /*und Gleichungsende*/
*buff.Entry = EQUAEND;
DecPointer(&buff);
DecPointer(&buff);
*buff.Entry = merker;
return(0); /*fertig*/
}
if (result = Resolvente(buff, optend, buff)) { /*Resolventen bilden*/
if (result == -1) /*Fehler aufgetreten?*/
return(-1); /*ja, dann Fehlercode*/
else {
if (AddByte(&buff, numofpins_Opt)) /*VCC eintragen*/
return(-1); /*und Gleichungsende*/
*buff.Entry = EQUAEND;
DecPointer(&buff);
DecPointer(&buff);
*buff.Entry = merker;
return(0); /*fertig*/
}
}
optend = buff;
while (*optend.Entry) /*Gleichungsende suchen*/
IncPointer(&optend);
/*Absorptions-Gesetz anwenden: a + a * b <=> a */
/*Prinzip: Es wird der Produktterm "prodterm1" mit allen*/
/*andern ("prodterm2") verglichen und untersucht, ob einer*/
/*ein Teil von diesem ist. Wenn ja, wird der andere Produkt-*/
/*term gelöscht (mit EQUASKIP).*/
pos1 = prodterm1 = buff;
for (;;) {
pos2 = buff;
while (*pos2.Entry == EQUASKIP) /*gelöschte Prod.terme*/
IncPointer(&pos2); /*überspringen*/
for(;;) {
varfound = 0;
while (*prodterm1.Entry == EQUASKIP) /*gelöschte Prod.terme*/
IncPointer(&prodterm1); /*überspringen*/
while (*pos2.Entry) { /*in der Gleichung nach der*/
if (*pos2.Entry == *prodterm1.Entry) { /*Variable suchen, die als*/
varfound = 1; /*erstes im Prod.term steht*/
break;
}
IncPointer(&pos2);
}
if (!varfound) /*for-Schleife abbrechen, wenn*/
break; /*keine entsprechende Variable*/
/*gefunden wurde*/
prodterm2 = GetProdTermStart(pos2); /*Prod.term-Anfang suchen*/
while (*prodterm2.Entry == EQUASKIP) /*gelöschte Prod.terme*/
IncPointer(&prodterm2); /*überspringen*/
if (prodterm1 != prodterm2) {
pos1 = prodterm1; /*Prod.terme miteinander vergleichen*/
for (;;) {
pos2 = prodterm2;
prodfound = 0;
for (;;) {
if (*pos1.Entry == *pos2.Entry) {
prodfound = 1;
break;
}
IncPointer(&pos2);
if ((*pos2.Entry) && (*pos2.Entry != '+') && (*pos2.Entry != EQUASKIP))
IncPointer(&pos2);
else
break;
}
if (!prodfound)
break;
IncPointer(&pos1);
if ((*pos1.Entry) && (*pos1.Entry != '+') && (*pos1.Entry != EQUASKIP))
IncPointer(&pos1);
else
break;
}
if (prodfound)
KillProdTerm(prodterm2);
}
if (*pos2.Entry)
IncPointer(&pos2);
}
while((*pos1.Entry != '+') && (*pos1.Entry)) /*nächsten Prod.term suchen*/
IncPointer(&pos1);
if (!*pos1.Entry) /*kein Prod.term mehr da*/
break; /*dann fertig*/
IncPointer(&pos1);
prodterm1 = pos1;
}
DecPointer(&buff);
*buff.Entry = merker; /*Gleichung wieder herstellen*/
if (AddByte(&optend, EQUAEND)) /*Gleichungsende wieder durch*/
return(-1); /*EQUAEND markieren*/
if (AddByte(&optend, 0))
return(-1);
return(0);
}
/* Resolvente: hängt eine neue Schicht von Resolventen an die
zu optimierende Gleichung an
Aufruf : result = Resolvente(optstart,optend,alteSchicht);
Parameter: optstart: ActBuffer-Struktur für Gleichungsanfang
optend : ActBuffer-Struktur für Gleichungsende
alteSchicht: ActBuffer-Stuktur für vorherige Schicht
Ergebnis : result = 0: alles o.k.
= 1: A + /A (VCC) gefunden=>Gleichung immer erfüllt
= -1: Fehler (kein freier Speicher mehr)
*/
int Resolvente(optstart, optend, alteSchicht)
struct ActBuffer optstart, optend, alteSchicht;
{
struct ActBuffer pos1, pos2, neueSchicht;
int result, flag, resflag; /*resflag: neue Resolvente*/
UBYTE var; /*gefunden?*/
/*neueSchicht: zeigt auf Stelle, an*/
/*der weitere Resolventen angefügt*/
/*werden können (Ende)*/
if ((*alteSchicht.Entry == '+') || (*alteSchicht.Entry == '*'))
IncPointer(&alteSchicht);
resflag = 0; /*lokale Variablen initialisieren*/
pos1 = alteSchicht;
neueSchicht = optend;
for (;;) {
var = *pos1.Entry; /*Variable (Pinnummer) holen*/
if (var & NEGATION) /*Variable negieren*/
var = var & (~NEGATION);
else
var = var | NEGATION;
pos2 = optstart; /*suche nach "/var"*/
for(;;) {
if (!SearchVar(&pos2,neueSchicht,var)) {
result = AddResolvente(pos1,pos2,optstart,&optend);
flag = 0; /*wenn die Variable ge-*/
while (pos2.Entry != neueSchicht.Entry) { /*funden wurde, wird pos2*/
if (*pos2.Entry == '+') { /*auf den nächsten Produktterm ge-*/
flag = 1; /*stellt. Wenn keiner da ist, bleibt*/
IncPointer(&pos2); /*flag 0 und weiter unten erfolgt*/
break; /*dann der Abbruch (if (!flag)..)*/
}
IncPointer (&pos2);
}
if (!result)
resflag = 1;
else {
if (result == 2) /*A + /A gefunden? => Ausdruck wahr*/
return(1); /*dann fertig*/
if (result == -1)
return(-1);
}
if (!flag) /*kein Produktterm mehr da?*/
break; /*dann Abbruch*/
}
else
break;
}
IncPointer(&pos1); /*Operator überspringen und pos1*/
if (pos1.Entry != neueSchicht.Entry) /*auf nächste Variable, falls nicht*/
IncPointer(&pos1); /*bereits der neue Schichtanfang*/
else /*erreicht wurde, sonst Abbruch*/
break;
}
if (!resflag) /*wurde neue Resolvente gefunden?*/
return(0); /*nein, dann fertig*/
else { /*ja, dann Rekursion*/
return (Resolvente(optstart, optend, neueSchicht));
}
}
/* NumOfVar: gibt die Anzahl der Variablen im Produktterm zurück
Aufruf : vars = NumOfVar(term);
Parameter: term: ActBuffer-Struktur auf Produktterm-Anfang
Ergebnis : vars: Integer-Variable - enthält die Anzahl
*/
int NumOfVar(term)
struct ActBuffer term;
{
int numofvar;
numofvar = 0;
for (;;) {
numofvar++;
IncPointer(&term);
if (!*term.Entry || (*term.Entry == '+'))
break;
IncPointer(&term);
}
return(numofvar);
}
/* AddResolvente: Fügt die beiden Produktterme in die "pos1" und "pos2"
zeigt zusammen, wobei die Variablen (Pinnummern) die unter "pos1"
und "pos2" stehen nicht berücksichtigt werden. Dann wird untersucht,
ob der neuentstandene Produktterm schon in der Gleichung steht.
Wenn nicht, wird der Produktterm an "equaend" angehängt.
Eine neue Resolvente ist geboren - welch' Dramatik.
Aufruf: result = AddResolvente(pos1,pos2,equastart,equaend);
Parameter: pos1, pos2 : ActBuffer-Struktur
equastart : ActBuffer-Struktur für Gleichungsanfang
equaend : Zeiger(!) auf ActBuffer-Struktur
Parametererklärung siehe obigen Text
Ergebnis : result = 0: es wurde eine Resolvente gebildet und angehängt
equaend zeigt auf neues Ende
= 1: keine Resolvente
= 2: A + /A wurde gefunden (VCC -> fertig)
= -1: Fehler, kein Speicher
*/
int AddResolvente(pos1, pos2, equastart, equaend)
struct ActBuffer pos1, pos2, equastart, *equaend;
{
struct ActBuffer pos, res, res1, res2, prodterm, nextprodterm;
int n, i, numofvar, numofvar1, numofvar2;
int found;
UBYTE *termbuff, *term, entry;
res1 = GetProdTermStart(pos1); /*ActBuffer-Struktur für den*/
res2 = GetProdTermStart(pos2); /*jeweiligen Produkttermanfang holen*/
if (res1 == res2) /* "a * /a" weglassen */
return(1);
numofvar1 = NumOfVar(res1); /*Anzahl der benötigten Bytes*/
numofvar2 = NumOfVar(res2); /*für die beiden Prod.terme holen*/
if (!(termbuff = (UBYTE *)AllocMem((long)(numofvar1+numofvar2+1),MEMF_PUBLIC|MEMF_CLEAR)))
return(-1);
/*hier werden die beiden Produktterme*/
numofvar = numofvar1; /*res1 und res2 zusammengehängt und*/
res = res1; /*in "termbuff" abgelegt (ohne '*'!)*/
pos = pos1;
for (i=0; i<2; i++) { /*zwei Produktterme*/
for (n=0; n<numofvar; n++) {
if (res.Entry != pos.Entry) {
term = termbuff; /*keine doppelten Pins zulassen*/
entry = *res.Entry;
found = 0;
while (*term) {
if (entry & NEGATION) { /* "a * /a" nicht zulassen*/
if (*term == (entry & (~NEGATION))) {
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(1);
}
}
else {
if (*term == (entry | NEGATION)) {
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(1);
}
}
if (*term == entry)
found = 1;
term++;
}
if (!found)
*term = entry;
}
IncPointer(&res);
IncPointer(&res);
}
numofvar = numofvar2;
res = res2;
pos = pos2;
}
if (!*termbuff) /*wenn termbuff leer ist, dann*/
*termbuff = numofpins_Opt; /*war A+/A in der Gleichung => VCC*/
/*untersuchen, ob der neue Prod.term*/
/*"termbuff" schon existiert*/
pos = equastart;
found = 0;
for(;;) {
prodterm = pos;
while ((*pos.Entry != '+') && (entry = *pos.Entry)) {
term = termbuff;
found = 0;
while (*term) {
if (*term == entry) {
found = 1;
break;
}
term++;
}
if (!found)
break;
IncPointer(&pos);
if (*pos.Entry == '*') /*'*' überspringen, falls vorhanden*/
IncPointer(&pos);
}
while ((*pos.Entry != '+') && (*pos.Entry)) /*nächsten Prod.term suchen*/
IncPointer(&pos);
nextprodterm = pos;
if (found) {
term = termbuff;
while (*term) {
pos = prodterm;
found = 0;
while ((*pos.Entry != '+') && (entry = *pos.Entry)) {
if (entry == *term) {
found = 1;
break;
}
IncPointer(&pos);
if (*pos.Entry == '*')
IncPointer(&pos);
}
if (!found)
break;
term++;
}
}
if (found)
break; /*for-Schleife verlassen*/
pos = nextprodterm;
if (!*pos.Entry)
break;
IncPointer(&pos);
}
if (!found) { /*existiert Prod.term schon ?*/
if (AddByte(equaend,'+')) { /*nein, dann an Gleichung anhängen*/
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(-1);
}
term = termbuff;
while (*term) {
if (AddByte(equaend,*term)) {
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(-1);
}
if (AddByte(equaend,'*')) {
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(-1);
}
term++;
}
DecPointer(equaend);
*equaend->Entry = 0; /*Endmarkierung*/
entry = *termbuff;
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
if (entry == numofpins_Opt) /*wenn VCC gefunden wurde,*/
return(2); /*dann 2 zurückgeben*/
else
return(0);
}
FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
return(1);
}
/* SearchVar: suche ab "pos" den Pin "var" bis nach "end"
Die Pinnummern werden jetzt als Variablen bezeichnet, da
sie ab jetzt wie Boolesche Variablen behandelt werden.
Aufruf : result = SearchVar(pos,end,var);
Parameter: pos : Zeiger auf ActBuffer-Struktur - Startposition ab
der gesucht werden soll
end : ActBuffer-Stuktur für Ende
var : Variable nach der gesucht werden soll
Ergebnis : result = 0: gefunden, pos zeigt auf Zeichen
= -1: nicht gefunden
*/
int SearchVar(pos, end, var)
register struct ActBuffer *pos, end;
register UBYTE var;
{
while (pos->Entry != end.Entry) { /*bis zum Ende suchen*/
if (*pos->Entry == var)
return(0);
IncPointer(pos);
}
return(-1);
}
/* WriteNewSource: Erstellt aus dem alten Source-File und der Liste der
neuen Gleichungen (optimiert) ein neues Source-File.
Dabei werden die Gleichungen aus dem alten Source-File
durch die neuen ersetzt.
Aufruf: result = WriteNewSource(buff, equastart, equaend);
Parameter: file: ActBuffer-Struktur für Liste der Gleichungen
in String-Form
equastart: Zeiger auf die Stelle im original Source-File,
an der die Gleichungen beginnen
equaend : Zeiger auf die Stelle im original Source-File,
an der die Gleichungen enden (DESCRIPTION)
Ergebnis : result = 0: alles o.k.
= -1: Fehler beim Schreiben
*/
int WriteNewSource(buff, equastart, equaend)
struct ActBuffer buff;
UBYTE *equastart, *equaend;
{
long result;
struct FileHandle *fh;
UBYTE *filebuffer, *filebuffer2;
if ((fh = Open(&path[0], MODE_NEWFILE))) {
/*Header des Source-Files schreiben*/
result = Write(fh, fbuff, (long)(equastart-fbuff));
if (result == -1L) { /*Fehler beim Schreiben?*/
Close(fh); /*ja, dann Ende*/
return(-1);
}
/*Gleichungen schreiben*/
for (;;) {
filebuffer = filebuffer2 = buff.Entry;
while (filebuffer2 < buff.BuffEnd) { /*Größe des Puffers bestimmen*/
if (!*filebuffer2)
break;
filebuffer2++;
}
result = Write(fh, filebuffer, (long)(filebuffer2-filebuffer));
if (result == -1L) { /*Fehler beim Schreiben?*/
Close(fh); /*ja, dann Ende*/
return(-1);
}
if (!buff.ThisBuff->Next) /*noch ein Puffer da?*/
break; /*nein, dann for(;;)-Ende*/
buff.ThisBuff = buff.ThisBuff->Next;
buff.Entry = (UBYTE *)(&buff.ThisBuff->Entries[0]);
buff.BuffEnd = (UBYTE *)buff.ThisBuff + (long)sizeof(struct Buffer);
}
/*Teil ab DESCRIPTION schreiben*/
result = Write(fh, equaend, (long)(fbuff+fsize-equaend));
if (result == -1L) { /*Fehler beim Schreiben?*/
Close(fh); /*ja, dann Ende*/
return(-1);
}
Close(fh);
}
else
return(-1);
return(0);
}
/* CopyEqua: Kopiert eine Gleichung aus dem Puffer from_buff in den
Puffer to_buff. Dabei werden unsinnige Konstruktionen
wie A*A*B*A, A * /A * B bereits voroptimiert.
Aufruf : result = CopyEqua(from_buff, to_buff);
Paramter: from_buff: ActBuffer-Struktur der Quelle (kein Zeiger!!!)
to_buff : ActBuffer-Struktur des Ziels (kein Zeiger!!!)
Ergebnis: 0: alles o.k. sonst: Fehler (kein Speicher)
*/
int CopyEqua(from_buff, to_buff)
struct ActBuffer from_buff, to_buff;
{
struct ActBuffer equastart, prodtermstart, pos;
UBYTE entry, pins[2*24];
register int n;
if (AddByte(&to_buff, *from_buff.Entry)) /*Ausganspin kopieren*/
return(-1);
IncPointer(&from_buff);
entry = *from_buff.Entry;
if ((entry == 'T') || (entry == 'R') || (entry == 'E')) {
if (AddByte(&to_buff, entry)) /*T,R,E kopieren*/
return(-1);
IncPointer(&from_buff);
}
/*Gleichung kopieren*/
equastart = prodtermstart = to_buff;
for (;;) {
for (n=0; n<2*24; pins[n++]=0);
for (;;) {
entry = *from_buff.Entry;
if (entry & NEGATION) {
if (pins[(entry&~NEGATION)-1]) { /* A * /A ? */
pos = prodtermstart; /*ja, dann Term im to_buff*/
while (pos.Entry != to_buff.Entry) { /*löschen und im from_buff*/
*pos.Entry = EQUASKIP; /*überspringen*/
IncPointer(&pos);
}
to_buff = prodtermstart;
while ((*from_buff.Entry != '+') && (*from_buff.Entry != EQUAEND))
IncPointer(&from_buff);
DecPointer(&from_buff);
}
else {
if (!pins[(entry&~NEGATION)-1+24]) { /*Pin mehrmals im Produktterm?*/
pins[(entry&~NEGATION)-1+24] = 1; /*nein, dann kopieren*/
if (AddByte(&to_buff, entry)) /*Pinnummer kopieren*/
return(-1);
}
}
}
else {
if (pins[entry-1+24]) { /* A * /A ? */
pos = prodtermstart; /*ja, dann Term im to_buff*/
while (pos.Entry != to_buff.Entry) { /*löschen und im from_buff*/
*pos.Entry = EQUASKIP; /*überspringen*/
IncPointer(&pos);
}
to_buff = prodtermstart;
while ((*from_buff.Entry != '+') && (*from_buff.Entry != EQUAEND))
IncPointer(&from_buff);
DecPointer(&from_buff);
}
else {
if (!pins[entry-1]) { /*Pin mehrmals im Produktterm?*/
pins[entry-1] = 1; /*nein, dann kopieren*/
if (AddByte(&to_buff, entry)) /*Pinnummer kopieren*/
return(-1);
}
}
}
IncPointer(&from_buff); /*Zeiger auf Operator oder */
entry = *from_buff.Entry; /*EQUAEND und in to_buff*/
if (entry == EQUAEND) { /*Ende erreicht?*/
DecPointer(&to_buff); /*ja, dann fertig*/
if (!((*to_buff.Entry == '+') || (*to_buff.Entry == '*')))
IncPointer(&to_buff); /* +,* am Ende wegmachen*/
if (AddByte(&to_buff, EQUAEND)) /*Endmarkierung setzen*/
return(-1);
return(0);
}
if (to_buff.Entry != equastart.Entry) { /*noch am Anfang?*/
DecPointer(&to_buff);
if (*to_buff.Entry != '+') {
if (*to_buff.Entry != '*') {
IncPointer(&to_buff);
if (AddByte(&to_buff, entry))
return(-1);
}
else {
if (entry == '+')
*to_buff.Entry = '+';
IncPointer(&to_buff);
}
}
else
IncPointer(&to_buff);
}
if (entry == '+') /*Produkttermende?*/
break; /*for-Schleife verlassen*/
IncPointer(&from_buff); /*Zeiger auf Pinnamen*/
}
prodtermstart = to_buff;
IncPointer(&from_buff);
}
}
/* PrintEqua: gibt eine Gleichung die mit ENDEQUAS oder ENDEQUA
abgeschlossen ist, auf dem Bildschirm aus
Aufruf: result = PrintEqua(buff,flag);
Parameter: buff: ActBuffer-Struktur (kein Zeiger!!!)
filebuff = 0: Ausgabe auf Bildschrim
= Zeiger auf ActBuffer-Struktur: Ausgabe in eine
verkettet List aus der dann später das neue
Source-File entsteht
Ergebnis : result = 0: alles o.k. sonst: Fehler (kein Speicher)
num_of_ORs, num_of_ANDs: enthält die Anzahl der vor-
gekommenen '+' und '*'
*/
int PrintEqua(buff, filebuff)
struct ActBuffer buff, *filebuff;
{
char estrng[SIZE_OF_EQUASTRING];
int n, entry, xoffset, notready;
num_of_ORs = num_of_ANDs = 0;
estrng[0] = 0; /*String löschen*/
entry = *buff.Entry;
if (entry & NEGATION) {
strcat(&estrng[0], (UBYTE *)"/");
entry = entry & (~NEGATION);
}
if (PinNamesOpt[entry-1][0] == '/')
strcat (&estrng[0], &PinNamesOpt[entry-1][1]); /*Ausgang*/
else
strcat (&estrng[0], &PinNamesOpt[entry-1][0]);
entry = GetNext(&buff);
if (entry == 'T') {
entry = GetNext(&buff);
strcat (&estrng[0], (UBYTE *)".T"); /*Typ des Ausgangs*/
}
else
if (entry == 'E') {
entry = GetNext(&buff);
strcat (&estrng[0], (UBYTE *)".E");
}
else
if (entry == 'R') {
entry = GetNext(&buff);
strcat (&estrng[0], (UBYTE *)".R");
}
strcat (&estrng[0], (UBYTE *)" = "); /*'='-Zeichen*/
xoffset = strlen(&estrng[0]); /*Stringlänge merken*/
notready = TRUE;
while (notready) {
while (strlen(&estrng[0]) < (SIZE_OF_EQUASTRING - 15)) {
if (entry & NEGATION) {
strcat(&estrng[0], (UBYTE *)"/");
entry = entry & (~NEGATION);
}
if (PinNamesOpt[entry-1][0] == '/') /*Pinnamen holen*/
strcat (&estrng[0], &PinNamesOpt[entry-1][1]);
else
strcat (&estrng[0], &PinNamesOpt[entry-1][0]);
if ((entry = GetNext(&buff)) == EQUAEND) {
notready = FALSE;
break;
}
if (entry == '+') {
strcat(&estrng[0], (UBYTE *)" + "); /*Operator holen*/
num_of_ORs++;
}
else {
strcat(&estrng[0], (UBYTE *)"*");
num_of_ANDs++;
}
if ((entry = GetNext(&buff)) == EQUAEND) {
notready = FALSE;
break;
}
}
if (!filebuff)
PrintOptText(&estrng[0]); /*eine Zeile ausgeben*/
else {
n = 0; /*String in Liste schreiben*/
while (estrng[n]) {
if (AddByte(filebuff,estrng[n])) /*Zeichen in Liste schreiben*/
return(-1);
n++;
}
if (AddByte(filebuff,0x0A)) /*Return eintragen*/
return(-1);
}
for (n=0; n<xoffset; n++) /*bis zu xoffset mit ' '*/
estrng[n] = ' '; /*füllen*/
estrng[xoffset] = 0; /*Rest vom String löschen*/
}
if (filebuff) /*File-Liste erzeugen?*/
if (AddByte(filebuff,0x0A)) /*nach einer Gleichung*/
return(-1); /*noch ein Return eintragen*/
return(0);
}
/* GetNext: holt den nächsten gültigen! Eintrag aus dem Puffer mit
der Struktur buff
Aufruf: entry = GetNext(buff);
Parameter: buff: Zeiger auf ActBuffer-Struktur
Ergebnis : entry: nächter Eintrag, der kein EQUASKIP ist
*/
int GetNext(buff)
struct ActBuffer *buff;
{
do
IncPointer(buff);
while (*buff->Entry == EQUASKIP);
return(*buff->Entry);
}
/*GetNextEqua : Sucht innerhalb des Puffers in dem die gesamten Gleichung
codiert abgelegt sind, nach der nächsten Gleichung
Aufruf: result = GetNextEqua(buff);
Parameter: buff : Zeiger auf ActBuffer-Stuktur
Ergebnis : FALSE : keine Gleichung mehr im Puffer
TRUE : noch mindestens eine Gleichung im Puffer
buff : Zeiger auf ActBuffer-Struktur, entsprechend gefüllt
*/
int GetNextEqua(buff)
struct ActBuffer *buff;
{
while (*buff->Entry != EQUAEND)
IncPointer(buff);
IncPointer(buff);
if (*buff->Entry == EQUASEND)
return(FALSE);
else
return(TRUE);
}
/* PrintOptText : gibt einen Text im Optimizer-Window aus
es wird automatisch gescrollt, wenn der Platz nicht
mehr ausreicht
Parameter: txt: Zeiger auf String
globale Variablen: oypos: y-Pos. an der der Text ausgegben
werden soll
Ergebnis : ---
*/
void PrintOptText(txt)
UBYTE *txt;
{
if (oypos<140)
oypos += 10;
else {
if (reqflag) {
ScrollRequester();
reqflag = FALSE;
}
scrolls++;
ScrollRaster(orp,0L,10L,30L,23L,630L,142L);
}
Move(orp,30L,(long)oypos);
Text(orp,txt,(long)strlen(txt));
if (scrolls == 11) {
scrolls = 1;
ScrollRequester();
}
}
/*ScrollRequester : öffnet einen Requester und wartet auf Tastendruck
oder auf Anklicken des "Weiter"-Gadgets
Parameter: keine
Ergebnis : -1: Requester konnte nicht geöffnet werden
0: weiter
*/
int ScrollRequester()
{
struct IntuiMessage *imsg;
ULONG class;
if (Request(&ScrollReq,optwin)) {
for (;;) {
imsg = (struct IntuiMessage *)GetMsg(optwin->UserPort);
if (!imsg) WaitPort (optwin->UserPort);
else {
class = imsg->Class;
ReplyMsg(imsg);
if (class == VANILLAKEY) {
EndRequest(&ScrollReq,optwin);
return(0);
}
if (class == GADGETUP) {
EndRequest(&ScrollReq,optwin);
return(0);
}
}
}
}
else return(-1);
}
/* TranslateEqua:
Übersetzt die Booleschen Gleichungen aus der String-Form
in eine codierte Form, so daß sie durch den Optimizer
leichter bearbeitet werden können.
Codierung: Pinname -> Pinnummer
/Pinname -> Pinnummer mit gesetztem Bit 7
T,R,E,+,* -> T,R,E,+,*
CR,LF,'.','=' werden weggelassen
Aufruf : result = TransLateEqua(buff)
Parameter: buff : Zeiger auf ActBuffer-Struktur
Ergebnis: 0: alles o.k. sonst: Fehler
actptr: Zeiger auf Ende der Gleichungen
*/
int TranslateEqua(buff)
struct ActBuffer *buff;
{
UBYTE chr, entry;
if (GetNextChar()) { /*Dateiende?*/
AsmError(2); /*ja, dann Fehler*/
return(-1);
}
/*Gleichungen vorhanden?*/
if (!strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) {
AsmError(33); /*nein, dann Fehlermeldung*/
return(-1);
}
for (;;) {
IsPinName(&PinNamesOpt[0], numofpins_Opt);
if (!actPin.p_Pin) { /*Pinname?*/
AsmError(11); /*nein, dann Fehler*/
return(-1);
}
if (actPin.p_Neg)
entry = actPin.p_Pin | NEGATION;
else
entry = actPin.p_Pin;
if (AddByte(buff,entry))
return(-1);
if (*actptr == '.') {
actptr++;
chr = *actptr++;
if (!((chr == 'T') || (chr == 'E') || (chr == 'R'))) {
AsmError(13);
return(-1);
}
if (AddByte(buff,chr))
return(-1);
}
if (GetNextChar()) { /*Dateiende?*/
AsmError(2); /*ja, dann Fehler*/
return(-1);
}
if (*actptr != '=') { /* '=' ?*/
AsmError(14); /*nein, dann Fehler*/
return(-1);
}
actptr++;
if (GetNextChar()) { /*Dateiende?*/
AsmError(2); /*ja, dann Fehler*/
return(-1);
}
for (;;) {
IsPinName(&PinNamesOpt[0], numofpins_Opt);
if (!actPin.p_Pin) { /*Pinname?*/
AsmError(11); /*nein, dann Fehler*/
return(-1);
}
if (actPin.p_Neg)
entry = actPin.p_Pin | NEGATION;
else
entry = actPin.p_Pin;
if (AddByte(buff,entry))
return(-1);
if (GetNextChar()) { /*Dateiende?*/
AsmError(2); /*ja, dann Fehler*/
return(-1);
}
if (!((*actptr == '+') || (*actptr == '*'))) { /*'+' oder '*'?*/
if (strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) { /*DESCRIPTION? */
if (AddByte(buff,EQUAEND)) /*Markierung für das Ende einer*/
return(-1); /*Gleichung*/
break; /*nein, dann innere Endlosschleife beenden*/
}
else {
if (AddByte(buff,EQUAEND)) /*Markierung für das Ende einer*/
return(-1); /*Gleichung*/
if (AddByte(buff,EQUASEND)) /*Markierung für das Ende aller*/
return(-1); /*Gleichungen (danach kommt DESCRIPTION)*/
return(0); /*alle Gleichungen übersetzt - Ende*/
}
}
if (AddByte(buff,*actptr))
return(-1);
actptr++;
if (GetNextChar()) { /*vorzeitiges Dateiende?*/
AsmError(2); /*ja, dann Fehler*/
return(-1);
}
}
}
}